/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.LoginAdmin;

import managedbean.Workspace.WorkspaceManagerBean;
import com.sun.jersey.core.util.Base64;
import java.io.IOException;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.validator.ValidatorException;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import merlion.common.entity.Staff;
import merlion.common.entity.SystemUserAccount;
import merlion.common.session.stateless.AdminSession;
import merlion.common.session.stateless.LogTrackingSessionBeanLocal;
import merlion.common.session.stateless.SystemUserSessionBeanLocal;
import merlion.common.util.Consts;
import merlion.common.util.CryptographicHelper;
import merlion.common.util.exception.NotExistException;
import merlion.common.util.exception.UpdateFailureException;
import org.primefaces.event.FlowEvent;
import servlet.SimpleCaptcha;

/**
 *
 * @author Zhang Ying
 */
@ManagedBean
@ViewScoped
public class LoginManagerBean {

    public static final String AUTH_KEY = "app.user.name";
    @EJB
    private AdminSession adminSession;
    @EJB
    private SystemUserSessionBeanLocal systemUserManager;
    @EJB
    private LogTrackingSessionBeanLocal logManager;
    @ManagedProperty(value = "#{workspaceManagerBean}")
    private WorkspaceManagerBean workspaceManagerBean;
    private String statusMessage;
    private String username;
    private String password;
    // for account activation
    private SystemUserAccount sua;
    private boolean accountValid;
    // for captcha
    private boolean renderedCaptcha;
    private String inputtedCaptcha;
    // for secure password reset
    private String inputtedEmail;
    private String secureQns;
    private String inputtedAns;
    private String newPassword;
    private String oldPassword;
    private Integer populate;
    // for automatic account blocked out
    // paths defined
    private String loginAdminPath = "/LoginAdmin/";
    private String workspacePath = "/Workspace/";
    private String rootPath = "/";
    private String pageRedirectAttribute = "?faces-redirect=true";

    /** Creates a new instance of LoginManagerBean */
    public LoginManagerBean() {
        username = "";
        password = "";
        inputtedCaptcha = "";
        inputtedEmail = "";
        secureQns = "";
        inputtedAns = "";
        newPassword = "";
        statusMessage = "";
        accountValid = Boolean.FALSE;
        renderedCaptcha = Boolean.FALSE;
    }

    // Login authentications
    public String login() {
        System.out.println("logging in intialized");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, null);
        if (workspaceManagerBean.getLoginCounts() > 4) {
            // forbid user to login too many times for one session
            statusMessage = "Sorry. You are not allowed to log in because you have failed logging in for too many times";
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
            return null;
        }
        if (workspaceManagerBean.getLoginCounts() == 4) {
            if (!systemUserManager.checkUsernameExist(username)) {
                // forbid user to login too many times for one session
                workspaceManagerBean.incrementLoginCounts();
                statusMessage = "Sorry. You are not allowed to log in because you have failed logging in for too many times";
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                return null;
            } else {
                workspaceManagerBean.incrementLoginCounts();
                if (workspaceManagerBean.getPwdWrongCounts() == 4) {
                    // disable current session as well as disable the account if the user input pwd wrong for 4 times
                    SystemUserAccount suacc = systemUserManager.deactivateSystemUserAccount(username);
                    sendLoginFailEmail(username, null,
                            suacc.getEmailAddress(), null);
                    statusMessage = "Sorry. You are not allowed to log in for the current session because you have failed too many times."
                            + "\n\n Your account is also disabled. Please reactivate it from your email.";
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                    return null;
                } else {
                    // forbid user to login too many times for one session
                    statusMessage = "Sorry. You are not allowed to log in because you have failed logging in for too many times";
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                    return null;
                }
            }
        }
        // check captcha
        if (renderedCaptcha) {
            HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
            HttpSession session = request.getSession();
            String c = (String) session.getAttribute(SimpleCaptcha.CAPTCHA_KEY);
            if (!inputtedCaptcha.equals(c)) {
                workspaceManagerBean.incrementLoginCounts();
                statusMessage = Consts.LOGIN_CAPTCHA_WRONG + "\n\n Number of trials left: " + (5 - workspaceManagerBean.getLoginCounts());
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                return null;
            }
        }
        if (systemUserManager.checkUsernameExist(getUsername())) {
            // the account and passowrd must match and the account should be activated
            if (systemUserManager.checkSystemUserAccountMatch(getUsername(), getPassword())) {
                try {
                    Staff currentStaff = systemUserManager.getStaff(username);
                    // update logged in time
                    systemUserManager.updateLoginTime(username);
                    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, currentStaff);
                    workspaceManagerBean.setLoggedUsername(getUsername());
                    workspaceManagerBean.setCurrentStaff(currentStaff);
                    workspaceManagerBean.setLoginCounts(0);
                    workspaceManagerBean.setPwdWrongCounts(0);
                    // update auditLogs info
                    logManager.updateLogInfo(Consts.USER_LOGIN, currentStaff.getSystemUserAccount().getId());
                    workspaceManagerBean.updateCurrentStaff();
                    return getUnSSLRedirectPath(workspacePath, "home");
                    //return getRedirectPath(workspacePath, "home");
                } catch (NotExistException ex) {
                    // user name not exists
                    workspaceManagerBean.incrementLoginCounts();
                    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, null);
                    statusMessage = Consts.LOGIN_USERNAME_NOT_EXIST + "\n\n Number of trials left: " + (5 - workspaceManagerBean.getLoginCounts());
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                    return null;
                }
            } else {
                workspaceManagerBean.incrementLoginCounts();
                FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, null);
                if (!systemUserManager.checkAccountStatusActivated(getUsername())) {
                    statusMessage = "Account is not activated. Please activate the account through your email before logging in.";
                } else {
                    // username and password doesn't match
                    workspaceManagerBean.incrementWrongCounts();
                    statusMessage = Consts.LOGIN_USERNAME_PASSWORD_NOTMATCH + "\n\n Number of trials left: " + (5 - workspaceManagerBean.getLoginCounts());
                }
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                return null;
            }
        } else {
            workspaceManagerBean.incrementLoginCounts();
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, null);
            statusMessage = Consts.LOGIN_USERNAME_NOT_EXIST + "\n\n Number of trials left: " + (5 - workspaceManagerBean.getLoginCounts());
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
            return null;
        }
    }

    public boolean isLoggedIn() {
        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(AUTH_KEY) != null;
    }

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(AUTH_KEY);
        workspaceManagerBean.setLoggedUsername(null);
        workspaceManagerBean.setCurrentStaff(null);
        workspaceManagerBean.setLoginCounts(0);
        return null;
    }

    public void logoutAction(ActionEvent event) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(AUTH_KEY);
        workspaceManagerBean.setLoggedUsername(null);
        workspaceManagerBean.setCurrentStaff(null);
        workspaceManagerBean.setLoginCounts(0);
        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect(getRedirectPath("/merlion-war/LoginAdmin/", "logout.xhtml"));
        } catch (Exception ex) {
        }
    }

    // for secure login
    public boolean isRenderedCaptcha() {
        if (workspaceManagerBean.getLoginCounts() < 3 || workspaceManagerBean.getLoginCounts() > 4) {
            renderedCaptcha = Boolean.FALSE;
        } else {
            renderedCaptcha = Boolean.TRUE;
        }
        return renderedCaptcha;
    }

    //  for secure password reset and password reminder
    public void checkEmailExists(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String emailInputed = (String) value;
        if (!systemUserManager.checkEmailExist(emailInputed)) {
            statusMessage = Consts.LOGIN_EMAIL_NOT_EXIST;
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, Consts.LOGIN_EMAIL_NOT_EXIST, Consts.LOGIN_EMAIL_NOT_EXIST);
            throw new ValidatorException(message);
        }
        if (systemUserManager.checkAccountDisabled(emailInputed)) {
            statusMessage = "Account is disabled. Please activate it first.";
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Account is disabled.Please activate it first.", "Account is disabled.  Please activate it first.");
            throw new ValidatorException(message);
        }
    }

    public void checkSecureAnswer(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String inputtedAnswer = (String) value;
        if (!systemUserManager.checkSecureAnswer(inputtedEmail, inputtedAnswer)) {
            statusMessage = Consts.LOGIN_QNS_ANS_NOT_MATCH;
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage);
            throw new ValidatorException(message);
        }
    }

    public void validateSamePassword(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        UIInput passwordField = (UIInput) context.getViewRoot().findComponent("form1:pwd");
        if (passwordField == null) {
            throw new IllegalArgumentException(String.format("Unable to find component."));
        }
        String pwd = (String) passwordField.getValue();
        String confirmPassword = (String) value;
        if (!confirmPassword.equals(pwd)) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Passwords do not match", "Passwords do not match!");
            throw new ValidatorException(message);
        }
        setNewPassword(confirmPassword);
    }

    // for account activation
    public boolean isAccountValid() {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, null);
        if (accountValid != Boolean.TRUE) {
            workspaceManagerBean.setLoginCounts(0);
            HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
            String parameter = request.getParameter("token");
            // need to check and update token
            if (systemUserManager.isTokenValid(parameter)) {
                // valid token, update DB
                try {
                    sua = systemUserManager.updateSystemUserAccountStatus(parameter);
                    // logged the user in
//                    systemUserManager.updateLoginTime(sua.getUsername());
//                    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, sua.getStaff());
//                    workspaceManagerBean.setLoggedUsername(sua.getUsername());
//                    workspaceManagerBean.setCurrentStaff(sua.getStaff());
//                    workspaceManagerBean.setLoginCounts(0);
//                    workspaceManagerBean.setPwdWrongCounts(0);
                    accountValid = Boolean.TRUE;
                    // wait for the user to change the password initially
                } catch (UpdateFailureException ex) {
                    // auto loggout if have logged in
                    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, null);
                    workspaceManagerBean.setLoggedUsername(null);
                    workspaceManagerBean.setCurrentStaff(null);
                    accountValid = Boolean.FALSE;
                    workspaceManagerBean.incrementLoginCounts();
                }
            } else {
                // auto loggout if have logged in
                workspaceManagerBean.setLoggedUsername(null);
                workspaceManagerBean.setCurrentStaff(null);
                accountValid = Boolean.FALSE;
                workspaceManagerBean.incrementLoginCounts();
            }
        }
        return accountValid;
    }

    public void checkOldPassword(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String oldpwd = (String) value;
        if (!systemUserManager.checkSystemUserAccountMatchDisabled(sua.getUsername(), oldpwd)) {
            System.out.println("useranme:"+sua.getUsername() + "oldpwd:"+ oldpwd);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Old password is not correct.", "Old password is not correct.");
            throw new ValidatorException(message);
        }
    }

    public String reactivateAccount() {
        try {
            Staff currentStaff = systemUserManager.activateSytemUserAccount(sua);
//            // update logged in time
//            systemUserManager.updateLoginTime(sua.getUsername());
//            // logged the user in
//            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, sua.getStaff());
//            workspaceManagerBean.setLoggedUsername(sua.getUsername());
//            workspaceManagerBean.setCurrentStaff(sua.getStaff());
//            workspaceManagerBean.setLoginCounts(0);
//            workspaceManagerBean.setPwdWrongCounts(0);
//            // update auditLogs info
//            logManager.updateLogInfo(Consts.USER_LOGIN, currentStaff.getSystemUserAccount().getId());
//            workspaceManagerBean.updateCurrentStaff();
//            return getUnSSLRedirectPath(workspacePath, "home");
            return getSSLRedirectPath(loginAdminPath, "login");
        } catch (UpdateFailureException ex) {
            return getRedirectPath(loginAdminPath, "error");
        }
    }

    public String activateAccount() {
        try {
            sua.setEncryptedPassword(newPassword);
            Staff currentStaff = systemUserManager.activateSytemUserAccount(sua);
            // update logged in time
            systemUserManager.updateLoginTime(sua.getUsername());
            // logged the user in
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, sua.getStaff());
            workspaceManagerBean.setLoggedUsername(sua.getUsername());
            workspaceManagerBean.setCurrentStaff(sua.getStaff());
            workspaceManagerBean.setLoginCounts(0);
            workspaceManagerBean.setPwdWrongCounts(0);
            // update auditLogs info
            logManager.updateLogInfo(Consts.USER_LOGIN, currentStaff.getSystemUserAccount().getId());
            workspaceManagerBean.updateCurrentStaff();
            return getUnSSLRedirectPath(workspacePath, "home");
        } catch (UpdateFailureException ex) {
            return getRedirectPath(loginAdminPath, "error");
        }
    }

    // redirection of path
    public String redirectToPasswordReminder() {
        statusMessage = "";
        return getRedirectPath(loginAdminPath, "passwordReminder");
    }

    public String redirectToLogout() {
        statusMessage = "";
        return getRedirectPath(loginAdminPath, "logout");
    }

    public String onFlowProcess(FlowEvent event) {
        String oldStep = event.getOldStep();
        String newStep = event.getNewStep();
        if (oldStep.equals("pwdNew") && newStep.equals("reset")) {
        }
        return event.getNewStep();
    }

    public void passwordReset(ActionEvent event) {
        // after reset the password, disable the account, create and save a new token, and send a new re-activation email
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(AUTH_KEY, null);
        SystemUserAccount suacc = systemUserManager.getSystemUserAccount(inputtedEmail);
        try {
            // update the password and disable the account
            suacc.setEncryptedPassword(newPassword);
            suacc.setStatus(Consts.ACCOUNT_DISABLED);
            systemUserManager.updateSystemUserAccount(suacc);
            CryptographicHelper cryptographicHelper = new CryptographicHelper();
            String token = Base64.encode(cryptographicHelper.doMD5Hashing(suacc.getUsername() + "." + newPassword)).toString();
            sendReactivationEmail(suacc.getUsername(), newPassword,
                    suacc.getEmailAddress(), token);
            if (token != null) {
                //save the token to the database
                try {
                    systemUserManager.updateStaffToken(suacc.getUsername(), token);
                } catch (UpdateFailureException ex) {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Saving token not successful."));
                }
            }
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                    "Successful", "Your password has been reset. To re-activate your account, please go to your email box and click on the re-activation link.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        } catch (UpdateFailureException ex) {
            ex.printStackTrace();
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful", "Updating password not successful."));
        }
    }

    // setters and getters for private fields 
    public String getNewPassword() {
        return newPassword;
    }

    public void setNewPassword(String newPassword) {
        this.newPassword = newPassword;
    }

    public String getInputtedAns() {
        return inputtedAns;
    }

    public void setInputtedAns(String inputtedAns) {
        this.inputtedAns = inputtedAns;
    }

    public String getSecureQns() {
        secureQns = systemUserManager.getSecureQuestion(inputtedEmail);
        return secureQns;
    }

    public String getInputtedEmail() {
        return inputtedEmail;
    }

    public void setInputtedEmail(String inputtedEmail) {
        this.inputtedEmail = inputtedEmail;
    }

    public String getInputtedCaptcha() {
        return inputtedCaptcha;
    }

    public void setInputtedCaptcha(String inputtedCaptcha) {
        this.inputtedCaptcha = inputtedCaptcha;
    }

    public SystemUserAccount getSua() {
        return sua;
    }

    public void setSua(SystemUserAccount sua) {
        this.sua = sua;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getOldPassword() {
        return oldPassword;
    }

    public void setOldPassword(String oldPassword) {
        this.oldPassword = oldPassword;
    }

    // private helper methods
    private String getRedirectPath(String parentPath, String actionPath) {
        return parentPath + actionPath + pageRedirectAttribute;
    }

    private String getUnSSLRedirectPath(String parentPath, String actionPath) {
        String serverName = FacesContext.getCurrentInstance().getExternalContext().getRequestServerName();
        String serverPort = "8080";
        String url = "http://" + serverName + ":" + serverPort + "/merlion-war"
                + parentPath + actionPath + ".xhtml";
        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect(url);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    private String getSSLRedirectPath(String parentPath, String actionPath) {
        String serverName = FacesContext.getCurrentInstance().getExternalContext().getRequestServerName();
        String serverPort = "8181";
        String url = "https://" + serverName + ":" + serverPort + "/merlion-war"
                + parentPath + actionPath + ".xhtml";
        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect(url);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    private String getForwardPath(String parentPath, String actionPath) {
        return parentPath + actionPath;
    }

    public void setWorkspaceManagerBean(WorkspaceManagerBean workspaceManagerBean) {
        this.workspaceManagerBean = workspaceManagerBean;
    }

    public void createTechStaff(ActionEvent actionEvent) {
        try {
            adminSession.createTechStaff();
            System.out.println("called finished create tech staff");
        } catch (Exception ex) {
            System.out.print("Error in creating tech staff.");
        }
    }
    
    public void createJunitTestData(ActionEvent actionEvent) {
        try {
            adminSession.createJunitTestData();
            System.out.println("called finished create Junit Test Data");
        } catch (Exception ex) {
            System.out.print("Error in creating Junit Test Data.");
        }
    }

    // private methods for sending email to the queue
    private void sendReactivationEmail(String username, String password, String emailAddr, String token) {
        // send the email to MDB
        try {
            Context c = new InitialContext();
            ConnectionFactory cf = (ConnectionFactory) c.lookup("jms/queueSendEmailFactory");
            Connection conn = null;
            Session s = null;

            try {
                conn = cf.createConnection();
                s = conn.createSession(false, s.AUTO_ACKNOWLEDGE);
                Destination destination = (Destination) c.lookup("jms/queueSendEmail");
                MessageProducer mp = s.createProducer(destination);
                MapMessage mmsg = s.createMapMessage();
                mmsg.setString("token", token);
                mmsg.setString("username", username);
                mmsg.setString("password", password);
                mmsg.setString("email", emailAddr);
                mmsg.setString("type", Consts.ACCOUNT_REACTIVATION);

                mp.send(mmsg);
            } catch (JMSException jmsEx) {
                jmsEx.printStackTrace();;
            } finally {
                if (s != null) {
                    s.close();
                }
                if (conn != null) {
                    conn.close();
                }
            }
        } catch (NamingException namingEx) {
            namingEx.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void sendLoginFailEmail(String username, String password, String emailAddr, String token) {
        // send the email to MDB
        try {
            Context c = new InitialContext();
            ConnectionFactory cf = (ConnectionFactory) c.lookup("jms/queueSendEmailFactory");
            Connection conn = null;
            Session s = null;

            try {
                conn = cf.createConnection();
                s = conn.createSession(false, s.AUTO_ACKNOWLEDGE);
                Destination destination = (Destination) c.lookup("jms/queueSendEmail");
                MessageProducer mp = s.createProducer(destination);
                MapMessage mmsg = s.createMapMessage();
                mmsg.setString("token", token);
                mmsg.setString("username", username);
                mmsg.setString("password", password);
                mmsg.setString("email", emailAddr);
                mmsg.setString("type", Consts.ACCOUNT_LOGIN_FAIL);

                mp.send(mmsg);
            } catch (JMSException jmsEx) {
                jmsEx.printStackTrace();;
            } finally {
                if (s != null) {
                    s.close();
                }
                if (conn != null) {
                    conn.close();
                }
            }
        } catch (NamingException namingEx) {
            namingEx.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public void populateSalesOrderData(ActionEvent event){
        adminSession.randomizeSalesOrder(populate);
    }

    public Integer getPopulate() {
        return populate;
    }

    public void setPopulate(Integer populate) {
        this.populate = populate;
    }
    
}
